package g

import (
	"net/rpc"
	"sync"
	"time"

	"github.com/toolkits/net"
)

type SingleConnRpcClient struct {
	sync.Mutex
	rpcClient *rpc.Client
	RpcServer string
	Timeout   time.Duration
}

// close Func
func (this *SingleConnRpcClient) close() {
	if this.rpcClient != nil {
		this.rpcClient.Close()
		this.rpcClient = nil
	}
}

// Call Func
func (this *SingleConnRpcClient) Call(method string, args interface{}, reply interface{}) error {
	this.Lock()
	defer func() {
		this.Unlock()
		this.close()
	}()

	var err error

	this.rpcClient, err = net.JsonRpcClient("tcp", this.RpcServer, this.Timeout)

	if err != nil {
		return err
	}

	timeout := time.Duration(50 * time.Second)
	done := make(chan error)

	go func() {
		err := this.rpcClient.Call(method, args, reply)
		done <- err
	}()

	select {
	case <-time.After(timeout):
		Logger.Info("[WARN] rpc call timeout %v => %v", this.rpcClient, this.RpcServer)
	case err = <-done:
		if err != nil {
			return err
		}
	}

	return err
}
